package com.hsogoo.collate.aop;

import com.hsogoo.collate.datasource.DataSourceCreator;
import com.hsogoo.collate.datasource.DataSourceHolder;
import com.hsogoo.collate.datasource.DynamicDataSourceContextHolder;
import com.hsogoo.collate.domain.DataSourceConfig;
import com.hsogoo.collate.domain.DynamicQuery;
import com.hsogoo.collate.mapper.DataSourceConfigMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;

/**
 * @Author huangsaigang
 * Created @2019-10-27.
 */
@Aspect
@Order(-10)//稍微优先级设高一点
@Component
@Slf4j
public class DynamicDataSourceAspect {

    @Autowired
    private DataSourceConfigMapper dataSourceConfigMapper;

    /**
     * 切换数据源
     * @param point
     * @param dynamicQuery
     */

    @Before("execution(* com.hsogoo.collate.mapper.DynamicMapper.*(..)) && args(dynamicQuery)")
    public void switchDataSource(JoinPoint point, DynamicQuery dynamicQuery) {

        if (!DynamicDataSourceContextHolder.containDataSourceKey(dynamicQuery.getDataSourceName())) {
            log.info("dataSource [{}] doesn't exist, try load dataSource from db",dynamicQuery.getDataSourceName());
            DataSourceConfig dataSourceConfig = dataSourceConfigMapper.getDataSourceConfig(dynamicQuery.getDataSourceName());
            if (dataSourceConfig == null) {
                String exception = String.format("DataSource [%s] doesn't exist, and try load from db failed", dynamicQuery.getDataSourceName());
                throw new RuntimeException(exception) ;
            }
            //创建新的数据源
            DataSource dataSource = DataSourceCreator.createDataSource(dataSourceConfig);
            //并保存到DataSourceHolder里
            DataSourceHolder.addDataSource(dynamicQuery.getDataSourceName(), dataSource);
        }
        // 切换数据源
        DynamicDataSourceContextHolder.setDataSourceKey(dynamicQuery.getDataSourceName());
        log.info("DynamicDataSourceAspect current thread id {}", Thread.currentThread().getId());
        log.info("Switch DataSource to [" + DynamicDataSourceContextHolder.getDataSourceKey()
                + "] in Method [" + point.getSignature() + "]");

    }

    /**
     * 重置数据源
     * @param point
     * @param dynamicQuery
     */
    @After("execution(* com.hsogoo.collate.mapper.DynamicMapper.*(..)) && args(dynamicQuery)")
    public void restoreDataSource(JoinPoint point, DynamicQuery dynamicQuery) {
        // 将数据源置为默认数据源
        DynamicDataSourceContextHolder.clearDataSourceKey();
        log.info("Restore DataSource to [" + DynamicDataSourceContextHolder.getDataSourceKey()
                + "] in Method [" + point.getSignature() + "]");
    }
}
